package com.liuqianfei.markme.rules.inline;

import com.liuqianfei.markme.core.Token;
import com.liuqianfei.markme.rules.AbstractState;
import com.liuqianfei.markme.rules.Delimiter;
import com.liuqianfei.markme.rules.EmphasisLikeScanResult;
import com.liuqianfei.markme.rules.IAction;

/**
 * Process *this* and _that_
 * @author liuqianfei
 */
public class EmphasisTokenizeAction implements IAction
{
    // Insert each marker as a separate text token, and add it to delimiter list
    //
    @Override
    public boolean parse(AbstractState state, boolean silent, int startLine, int endLine)
    {
        EmphasisLikeScanResult scanned;

        Token token;
        int start = state.getPos();
        char marker = state.getSrc().charAt(start);

        if (silent)
            return false;

        if (marker != 0x5F /* _ */ && marker != 0x2A /* * */)
            return false;

        scanned = state.scanDelims(state.getPos(), marker == 0x2A);

        for (int i = 0; i < scanned.length; i++)
        {
            token         = state.push("text", "", 0);
            token.content = String.valueOf(marker);

            Delimiter delimiter = new Delimiter();
            // Char code of the starting marker (number).
            //
            delimiter.marker = marker;
            // Total length of these series of delimiters.
            //
            delimiter.length = scanned.length;
            // An amount of characters before this one that's equivalent to
            // current one. In plain English: if this delimiter does not open
            // an emphasis, neither do previous `jump` characters.
            //
            // Used to skip sequences like "*****" in one step, for 1st asterisk
            // value will be 0, for 2nd it's 1 and so on.
            //
            delimiter.jump = i;
            // A position of the token this delimiter corresponds to.
            //
            delimiter.token = state.getTokens().size() - 1;
            // Token level.
            //
            delimiter.level = state.getLevel();
            // If this delimiter is matched as a valid opener, `end` will be
            // equal to its position, otherwise it's `-1`.
            //
            delimiter.end = -1;
            // Boolean flags that determine if this delimiter could open or close
            // an emphasis.
            //
            delimiter.open = scanned.can_open;
            delimiter.close = scanned.can_close;

            state.getDelimiters().add(delimiter);
        }

        state.setPos(state.getPos() + scanned.length);

        return true;
    }
}
